var fieldTypes = Class.create();
fieldTypes.prototype = {
    // The Id is used to query the JSON database.
    initialize: function(name) {
        this.name = name;
        this.types = [];
    },
    add: function(obj) {
        this.types.push(obj);
    },

    get: function(type) {
        el = this.types.detect(function(obj){return obj.type == type;});
        return el;
    }
}

var ft = new fieldTypes('');

ft.add({ type:'text',
    name:'文本',
    properties: new Array('types', 'size', 'required', 'unique', 'isPrivate', 'textDefault'),
    display: function(id) {
        divClass = 'text ' + fs.get(id, 'size');
        divId   = 'field' + id;

        return  Builder.node('div',[
            Builder.node('input', {type:'text', readonly:'readonly', id:divId, className:divClass})
        ]);
    }
});

ft.add({ type:'textarea',
    name:'多行文本',
    properties: new Array('types', 'size', 'required', 'unique', 'isPrivate', 'textDefault'),
    display: function(id) {
        divClass = 'textarea ' + fs.get(id, 'size');
        divId   = 'field' + id;
        return  Builder.node('div',[
            Builder.node('textarea', {type:'text', readonly:'readonly', id:divId, className:divClass, rows:'',cols:''})
        ]);
    }
});

ft.add({ type:'checkbox',
    name:'选择框',
    properties: new Array('types', 'choices', 'required', 'isPrivate'),
    display: function(id) {
        fieldId = 'field' + id;
        fieldOptions = fs.get(id, 'options');
        checkgroup = Builder.node('span', {id:fieldId});

        for(i = 0; i < fieldOptions.length; i++) {
            fieldVal = fieldOptions[i].option;
            if(fieldVal == '') fieldVal = '&nbsp;';
            if(fieldOptions[i].isDefault == 1) box = Builder.node('input', {className:'checkbox', type:'checkbox', checked:'checked'});
            else box = Builder.node('input', {className:'checkbox', type:'checkbox'});
            checkgroup.appendChild(box);
            fieldLabel = Builder.node('label', {className:'choice'});
            fieldLabel.innerHTML = fieldVal;
            checkgroup.appendChild(fieldLabel);
        }

        return checkgroup;
    }
});

ft.add({ type:'date',
    name:'日期',
    properties: new Array('types', 'required', 'unique', 'isPrivate', 'date', 'textDefault'),
    display: function(id) {
        return Builder.node('div', [
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'4'}), ' - ',
                        Builder.node('label', '年')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}), ' - ',
                        Builder.node('label', '月')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}), ' - ',
                        Builder.node('label', '日')
                    ]),
                    Builder.node('img', {src:'css/images/icons/calendar.png',alt:'Pick Date.', className:'icon'})
            ]);
    }
});

ft.add({ type:'file',
    name:'附件',
    properties: new Array('types', 'required', 'isPrivate'),
    display: function(id) {
        return Builder.node('div', [
                    Builder.node('img', {src:'css/images/icons/page_white_get.png', className:'icon', alt:'Attach File.'}),
                    Builder.node('div', [
                        Builder.node('input', {className:'text',readonly:'readonly', type:'file'})
                    ])
                ]);
    }
});

ft.add({ type:'select',
    name:'下拉',
    properties: new Array('types', 'size','choices', 'isPrivate'),
    display: function(id) {
    }
});
ft.add({ type:'radio',
    name:'单选框',
    properties: new Array('types','choices', 'required', 'randomize', 'isPrivate'),
    display: function(id) {
    }
});
ft.add({ type:'time',
    name:'时间',
    properties: new Array('types', 'required', 'unique', 'isPrivate'),
    display: function(id) {
    }
});
ft.add({ type:'phone',
    name:'电话号码',
    properties: new Array('types', 'required', 'unique', 'isPrivate', 'phone', 'phoneDefault'),
    display: function(id) {
    }
});
ft.add({ type:'money',
    name:'金额',
    properties: new Array('types', 'required', 'unique', 'isPrivate', 'currency'),
    display: function(id) {
    }
});
ft.add({ type:'number',
    name:'数字',
    properties: new Array('types', 'size', 'required', 'unique', 'isPrivate', 'textDefault'),
    display: function(id) {
    }
});

/*-----------------------------------
         WHAT TO SHOW
------------------------------------*/
/*

show['date']            = new Array('types', 'required', 'unique', 'isPrivate', 'date', 'textDefault');
show['eurodate']        = new Array('types', 'required', 'unique', 'isPrivate', 'date', 'textDefault');
show['time']            = ;
show['phone']           = new Array('types', 'required', 'unique', 'isPrivate', 'phone', 'phoneDefault');
show['europhone']       = new Array('types', 'required', 'unique', 'isPrivate', 'phone', 'textDefault');
show['address']         = new Array('types', 'required', 'unique', 'isPrivate', 'addressDefault');
show['money']           = new Array('types', 'required', 'unique', 'isPrivate', 'currency');
show['linked']          = new Array('types', 'required', 'unique', 'isPrivate');
show['url']             = new Array('types', 'size', 'required', 'unique', 'isPrivate', 'textDefault');
show['email']           = new Array('types', 'size', 'required', 'unique', 'isPrivate', 'textDefault');
show['number']          = ;
show['rating']          = new Array('types', 'option');
show['tags']            = new Array('types', 'option');
show['file']            = new Array('types', 'required', 'isPrivate');
show['password']        = new Array('types', 'option');
show['math']            = new Array('types', 'option');
show['section']         = new Array('types', 'isPrivate');
*/
/*-----------------------------------
               PROPERTIES
------------------------------------*/

var fieldProperties = Class.create();

fieldProperties.prototype = {

    // The Id is used to query the JSON database.
    initialize: function(id) {
        this.id = id;
    },

    // Loop through the show array child whose type is equal to the field type, and display the properties.
    display: function() {
        this.hideAll();
        this.title();
        var show = ft.get(fs.get(this.id, 'type')).properties;
        for(var x = 0; x < show.length; x++) {
            this[show[x]]();
        }

        this.instructions();
        $('fieldPos').innerHTML = (parseInt(fs.get(this.id, 'position'))+1)+'.';


        $('fieldPos').style.display = 'block';
        $('allProps').style.display = 'block';
        $('listButtons').style.display = 'block';
    },

    hideAll: function() {
        $('listSecurity').style.display = 'none';
        $('listType').style.display = 'none';
        $('listRandomize').style.display = 'none';
        $('listTextDefault').style.display = 'none';
        $('listPhoneDefault').style.display = 'none';
        $('listAddressDefault').style.display = 'none';
        $('listDateFormat').style.display = 'none';
        $('listPhoneFormat').style.display = 'none';
        $('listMoneyFormat').style.display = 'none';
        $('listSize').style.display = 'none';
        $('listNameFormat').style.display = 'none';
        $('listChoices').style.display = 'none';
        $('listOptions').style.display = 'none';
        $('noFieldSelected').style.display = 'none';
        $('listButtons').style.display = 'none';
        $('fieldPos').style.display = 'none';
        $('allProps').style.display = 'none';
    },

    title: function() {
        fieldVal = fs.get(this.id, 'title');
        $('fieldTitle').value = fieldVal;
    },

    instructions: function() {
        fieldVal = fs.get(this.id, 'instructions');
        $('fieldInstructions').value = fieldVal;
    },

    types: function() {
        $('listType').style.display = 'block';
        if(fs.get(this.id, 'hasDbColumn') == '1') $('fieldType').disabled = true;
        else $('fieldType').disabled = false;

        var type = fs.get(this.id, 'type');
        if(type == 'shortname') type = 'name';
        if(type == 'europhone') type = 'phone';
        if(type == 'eurodate') type = 'date';

        for(var i = 0; i < $('fieldType').options.length; i++) {
            if($('fieldType').options[i].value == type) {
                $('fieldType').options[i].selected = true;
                break;
            }
        }
    },

    size: function() {
        $('listSize').style.display = 'block';

        for(var i = 0; i < $('fieldSize').options.length; i++) {
            if($('fieldSize').options[i].value == fs.get(this.id, 'size')) {
                $('fieldSize').options[i].selected = true;
                break;
            }
        }
    },

    choices: function() {
        $('listChoices').style.display = 'block';
        $('fieldChoices').innerHTML = '';
        options = fs.get(this.id, 'options');
        ftype = fs.get(this.id, 'type');
        allHtml = new Array();
        for(var i = 0; i < options.length; i++) {
            fieldVal = options[i].option.replace(/\"/g,"&quot;");

            if(options[i].isDefault == 1) {
                loc = 'css/images/icons/star.gif';
                msg = 'Default.'
            }
            else {
                loc = 'css/images/icons/stardim.gif';
                msg = 'Make Default.';
            }
            allHtml[i] = '<li>' +
                        '<input id="choice'+i+'" class="text" type="text" maxlength="150" autocomplete="off" value="'+fieldVal+'" '+
                        'onkeyup="updateProperties(this.value, \'choices\', '+i+')" ' +
                        'onkeypress="choicesKeys(event,'+i+')" />'+
                        ' <img class="button" src="css/images/icons/add.png" alt="Add." title="Add." onclick="addChoice('+(i+1)+')" /> ' +
                        '<img class="button" src="css/images/icons/delete.png" alt="Delete." title="Delete." onclick="removeCheckbox('+options[i].id+', '+options[i].hasDbColumn+', \''+ftype+'\', '+i+')" /> ' +
                        '<img class="button" src="'+loc+'" alt="'+msg+'" title="'+msg+'" onclick="makeDefault('+i+')" />' +
                        '</li>';
        }
        $('fieldChoices').innerHTML = allHtml.join("");
    },

    required: function() {
        $('listOptions').style.display = 'block';
        (fs.get(activeField, 'isRequired') == '1')
            ? $('fieldRequired').checked = true
            : $('fieldRequired').checked = false;
        var ftype = fs.get(activeField, 'type');
        (ftype == 'checkbox' || ftype == 'radio')
            ? this.toggleUnique('hide')
            : this.toggleUnique('show');
    },

    toggleUnique: function(view) {
        uniques = document.getElementsByClassName('fieldUniqueToggle');
        for(var i = 0; i < uniques.length; i++) {
            (view == 'hide')
                ? uniques[i].style.visibility = 'hidden'
                : uniques[i].style.visibility = 'visible';
        }
    },

    unique: function() {
        (fs.get(activeField, 'isUnique') == '1')
            ? $('fieldUnique').checked = true
            : $('fieldUnique').checked = false;
    },

    isPrivate: function() {
        $('listSecurity').style.display = 'block';
        (fs.get(activeField, 'isPrivate')   == '1')
            ? $('fieldPrivate').checked = true
            : $('fieldPublic').checked = true;
    },

    randomize: function() {
        $('listRandomize').style.display = 'block';
        (fs.get(activeField, 'validation')  == 'rand')
            ? $('fieldRandom').checked = true
            : $('fieldNotRandom').checked = true;
    },

    textDefault: function() {
        $('listTextDefault').style.display = 'block';
        fieldVal = fs.get(this.id, 'defaultVal');
        $('fieldDefault').value = fieldVal;
    },

    phoneDefault: function() {
        $('listPhoneDefault').style.display = 'block';
        fieldVal = fs.get(this.id, 'defaultVal');
        $('fieldPhoneDefault1').value = fieldVal.substring(0, 3);
        $('fieldPhoneDefault2').value = fieldVal.substring(3, 6);
        $('fieldPhoneDefault3').value = fieldVal.substring(6, 10);
    },

    addressDefault: function() {
        $('listAddressDefault').style.display = 'block';
        fieldVal = fs.get(this.id, 'defaultVal');
        countries = $('fieldCountries');
        for(var i = 0; i < countries.options.length; i++) {
            if(countries.options[i].value == fieldVal) countries.selectedIndex = i;
        }
    },

    date: function() {
        $('listDateFormat').style.display = 'block';

        (fs.get(activeField, 'type')    == 'date')
            ? $('fieldDateAmerican').selected = true
            : $('fieldDateEuro').selected = true;
    },

    name: function() {
        $('listNameFormat').style.display = 'block';
        if(fs.get(this.id, 'hasDbColumn') == '1') $('nameFormat').disabled = true;
        else $('nameFormat').disabled = false;
        (fs.get(activeField, 'type') == 'shortname')
            ? $('fieldNameNormal').selected = true
            : $('fieldNameExtended').selected = true;
    },

    phone: function() {
        $('listPhoneFormat').style.display = 'block';
            (fs.get(activeField, 'type')    == 'phone')
            ? $('fieldPhoneAmerican').selected = true
            : $('fieldPhoneEuro').selected = true;
    },

    currency: function() {
        $('listMoneyFormat').style.display = 'block';
            if(fs.get(activeField, 'validation')    == 'euro') $('fieldMoneyEuro').selected = true ;
            else if(fs.get(activeField, 'validation')   == 'pound') $('fieldMoneyPound').selected = true ;
            else if(fs.get(activeField, 'validation')   == 'yen') $('fieldMoneyYen').selected = true ;
            else $('fieldMoneyAmerican').selected = true ;
    }

}
var field = Class.create();

field.prototype = {

    // Unique Id is given to the field. Data is pulled from the fieldset with this Id.
    initialize: function(id) {
        this.id =   id;
    },

    // Each field is within a <li>. Build the <li>, and then display the markup based off of the field type.
    display: function() {
        this.li = document.createElement('li');
        this.addMarkup();
        this.li.id = 'li_' + this.id;
        Element.addClassName(this.li, 'dragable');
        if (fs.get(this.id, 'isPrivate') == '1') Element.addClassName(this.li, 'private');

        return this.li;
    },

    // Add the inner markup to the <li>.
    addMarkup: function() {
        this.li.appendChild(Builder.node('a', {href:'#', className:'hvr', onclick:'return false;', title:'Click to edit. Drag to reorder.'}, [
                this.fieldLabel(),
                ft.get(fs.get(this.id, 'type')).display(this.id),
                this.additional()
        ]));
        this.li.innerHTML = '<div class="arrow" id="arrow"></div>' + this.li.innerHTML;
        this.li.appendChild(this.fieldActions());
    },

    // Change the class of a slected field, and display the arrow.
    selected: function() {
        Element.addClassName(this.li, 'editing');
    },

    // Remove the class and arrow from the field.
    unselect: function() {
        Element.removeClassName(this.li, 'editing');
    },

    /*-----------------------------------
                   FIELD MARKUP
    ------------------------------------*/

    fieldLabel: function() {
        labelId     = 'title'+this.id;
        labelVal = fs.get(this.id, 'title');
        var el = Builder.node('label',{className:'desc', id:labelId});
        el.innerHTML = labelVal;
        if(fs.get(this.id, 'isRequired') == '1') el.appendChild(Builder.node('span', {className:'req'}, ' *'));
        return el;
    },

    fieldActions: function() {
        return Builder.node('div',{className:'fieldActions'},[
                    Builder.node('img',{src:'css/images/icons/add.png', alt:'Duplicate.', title:'Duplicate.',
                                                onmousedown:'duplicateField('+this.id+')'}), ' ',
                    Builder.node('img',{src:'css/images/icons/delete.png', alt:'Delete.', title:'Delete.',
                                                onmousedown:'removeField('+this.id+')'})
                ]);
    },

/*
    text: function() {
        divClass = 'text ' + fs.get(this.id, 'size');
        divId   = 'field' + this.id;
        return  Builder.node('div',[
            Builder.node('input', {type:'text', readonly:'readonly', id:divId, className:divClass})
        ]);
    },

    textarea: function() {
        divClass = 'textarea ' + fs.get(this.id, 'size');
        divId   = 'field' + this.id;
        return  Builder.node('div',[
            Builder.node('textarea', {type:'text', readonly:'readonly', id:divId, className:divClass, rows:'',cols:''})
        ]);
    },

    checkbox: function() {
        fieldId = 'field' + this.id;
        fieldOptions = fs.get(this.id, 'options');
        checkgroup = Builder.node('span', {id:fieldId});

        for(i = 0; i < fieldOptions.length; i++) {
            fieldVal = fieldOptions[i].option;
            if(fieldVal == '') fieldVal = '&nbsp;';
            if(fieldOptions[i].isDefault == 1) box = Builder.node('input', {className:'checkbox', type:'checkbox', checked:'checked'});
            else box = Builder.node('input', {className:'checkbox', type:'checkbox'});
            checkgroup.appendChild(box);
            fieldLabel = Builder.node('label', {className:'choice'});
            fieldLabel.innerHTML = fieldVal;
            checkgroup.appendChild(fieldLabel);
        }

        return checkgroup;
    },

    select: function() {
        fieldId = 'field' + this.id;
        fieldClass = 'select ' + fs.get(this.id, 'size');
        fieldOptions = fs.get(this.id, 'options');
        select = Builder.node('select', {id:fieldId, className:fieldClass});

        for(i = 0; i < fieldOptions.length; i++) {
            if(fieldOptions[i].isDefault == 1) box = Builder.node('option', {selected:'selected'}, fieldOptions[i].option);
            else box = Builder.node('option', fieldOptions[i].option);
            select.appendChild(box);
        }

        return  Builder.node('div',[select]);
    },

    radio: function() {
        fieldId = 'field' + this.id;
        fieldOptions = fs.get(this.id, 'options');
        radiogroup = Builder.node('span', {id:fieldId});

        for(i = 0; i < fieldOptions.length; i++) {
            fieldVal = fieldOptions[i].option;
            if(fieldVal == '') fieldVal = '&nbsp;';
            if(fieldOptions[i].isDefault == 1) box = Builder.node('input', {checked:'checked', className:'radio', type:'radio', name:'radiogroup'});
            else box = Builder.node('input', {className:'radio', type:'radio', name:'radiogroup'});
            radiogroup.appendChild(box);
            fieldLabel = Builder.node('label', {className:'choice'});
            fieldLabel.innerHTML = fieldVal;
            radiogroup.appendChild(fieldLabel);
        }

        return radiogroup;
    },

    name: function() {
        return Builder.node('div', [
                    Builder.node('span', [
                        Builder.node('input', {type:'text', readonly:'readonly', className:'text', size:'2'}),
                        Builder.node('label', 'Title')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'12'}),
                        Builder.node('label', '姓')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'14'}),
                        Builder.node('label', '名')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'3'}),
                        Builder.node('label', 'Suffix')
                    ])
            ]);
    },

    shortname: function() {
        return Builder.node('div', [
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'12'}),
                        Builder.node('label', '姓')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'14'}),
                        Builder.node('label', '名')
                    ])
            ]);
    },

    date: function() {
        return Builder.node('div', [
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'4'}), ' 年 ',
                        Builder.node('label', 'MM')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}), ' 月 ',
                        Builder.node('label', 'DD')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}), ' 日 ',
                        Builder.node('label', 'YYYY')
                    ]),
                    Builder.node('img', {src:'css/images/icons/calendar.png',alt:'Pick Date.', className:'icon'})
            ]);
    },

    eurodate: function() {
        return Builder.node('div', [
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}), ' / ',
                        Builder.node('label', 'DD')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}), ' / ',
                        Builder.node('label', 'MM')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'4'}), ' ',
                        Builder.node('label', 'YYYY')
                    ]),
                    Builder.node('img', {src:'css/images/icons/calendar.png',alt:'Pick Date.', className:'icon'})
            ]);
    },

    time: function() {
        return Builder.node('div', [
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}), ' : ',
                        Builder.node('label', 'HH')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}), ' : ',
                        Builder.node('label', 'MM')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}),
                        Builder.node('label', 'SS')
                    ]),
                    Builder.node('span', [
                        Builder.node('select', {className:'select', style:'width:4em'}, [
                            Builder.node('option', 'AM'),
                            Builder.node('option', 'PM')
                        ]),
                        Builder.node('label', 'AM/PM')
                    ])
            ]);
    },

    phone: function() {
        return Builder.node('div', [
                    Builder.node('img', {src:'css/images/icons/telephone.png',alt:'Phone Number', className:'icon'}), ' ',
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'3'}), ' - ',
                        Builder.node('label', '(###)')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'3'}), ' - ',
                        Builder.node('label', '###')
                    ]),
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'4'}),
                        Builder.node('label', '####')
                    ])
                ]);
    },

    europhone: function() {
        divClass = 'text medium';
        divId   = 'field' + this.id;
        return Builder.node('div', {className:'full'}, [
                        Builder.node('img', {src:'css/images/icons/telephone.png',alt:'Phone Number', className:'icon'}), ' ',
                        Builder.node('input', {type:'text', readonly:'readonly', id:divId, className:divClass})
                    ])
    },

    address: function() {
        countries = Builder.node('div', {className:'right'});
        allCountries =  '<select class="select medium" name="">' +
                        '<option value=""></option>' +
                        '</select><label>Country</label>';
        countries.innerHTML = allCountries;

        return Builder.node('div', {className:'full'}, [
                    Builder.node('div', {className:'full'}, [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text large'}),
                        Builder.node('label', 'Street Address')
                    ]),
                    Builder.node('div', {className:'full'}, [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text large'}),
                        Builder.node('label', 'Address Line 2')
                    ]),
                    Builder.node('div', {className:'left'}, [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text medium'}),
                        Builder.node('label', 'City')
                    ]),
                    Builder.node('div', {className:'right'}, [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text medium'}),
                        Builder.node('label', 'State / Province / Region')
                    ]),
                    Builder.node('div', {className:'left'}, [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text medium'}),
                        Builder.node('label', 'Zip / Postal Code')
                    ]),
                    countries
                ]);
    },

    money: function() {
        currency = fs.get(this.id, 'validation');
        symbol = '$';
        bling = 'Dollars';
        baby = 'Cents';
        growth = '10';
        decimal = ' . '
        if(currency == 'euro') {symbol = '&#8364;';bling='Euros';baby='Cents';}
        if(currency == 'pound') {symbol = '&#163;';bling='Pounds';baby='Pence';}
        if(currency == 'yen') {symbol = '&#165;';bling='Yen';decimal='';growth='15'}
        domEl = Builder.node('span');
        domEl.innerHTML = symbol;
        mainEl = Builder.node('div', [
                    domEl,
                    Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:growth}),
                        decimal,
                        Builder.node('label', bling)
                    ]),
                ]);
        if(currency != 'yen') {
            mainEl.appendChild(Builder.node('span', [
                        Builder.node('input', {type:'text',readonly:'readonly', className:'text', size:'2'}),
                        Builder.node('label', baby)
                    ]));
        }
        return mainEl;
    },

    rating: function() {
        return Builder.node('div', [
                    Builder.node('ul', {className:'star-rating'}, [
                        Builder.node('li', [
                            Builder.node('a', {href:'1', onclick:'return false;', title:'1 star out of 5', className:'one-stars'}, 1)
                        ]),
                        Builder.node('li', [
                            Builder.node('a', {href:'2', onclick:'return false;', title:'2 stars out of 5', className:'two-stars'}, 2)
                        ]),
                        Builder.node('li', [
                            Builder.node('a', {href:'3', onclick:'return false;', title:'3 stars out of 5', className:'three-stars'}, 3)
                        ]),
                        Builder.node('li', [
                            Builder.node('a', {href:'4', onclick:'return false;', title:'4 stars out of 5', className:'four-stars'}, 4)
                        ]),
                        Builder.node('li', [
                            Builder.node('a', {href:'5', onclick:'return false;', title:'5 stars out of 5', className:'five-stars'}, 5)
                        ]),
                        Builder.node('li', {className:'current-rating', style:'width:16px'})
                    ]),
                    Builder.node('p', '1 out of 5 stars')
                ]);
    },

    math: function() {
        return Builder.node('div', [
                    Builder.node('img', {src:'css/images/icons/sum.png', alt:'Math Field.'}),
                    Builder.node('div', [
                        Builder.node('input', {className:'text',readonly:'readonly', type:'text', value:'42'}),
                        Builder.node('p', 'num1 + num2')
                    ])
                ]);
    },

    file: function() {
        return Builder.node('div', [
                    Builder.node('img', {src:'css/images/icons/page_white_get.png', className:'icon', alt:'Attach File.'}),
                    Builder.node('div', [
                        Builder.node('input', {className:'text',readonly:'readonly', type:'file'})
                    ])
                ]);
    },

    linked: function() {
        return Builder.node('div', [
                    Builder.node('img', {src:'css/images/icons/table_relationship.png', alt:'Form Linked Field.'}),
                    Builder.node('div', [
                        Builder.node('select', {className:'select'}, [
                            Builder.node('option', 'Field 1'),
                            Builder.node('option', 'Field 2'),
                            Builder.node('option', 'Field 3')
                        ]),
                        Builder.node('p', [Builder.node('strong', 'Form')], ' : Field')
                    ])
                ]);
    },

    password: function() {
        return Builder.node('input', {className:'text medium',value:'mypassword',readonly:'readonly', type:'password'});
    },

    tags: function() {
        return Builder.node('div', [
                    Builder.node('img', {src:'css/images/icons/tag_green.png', className:'icon', alt:'Tags.'}),
                    Builder.node('input', {className:'text tags', readonly:'readonly',type:'text'}), ' ',
                    Builder.node('p', [
                        Builder.node('a', {href:'#', onclick:'return false;', title:'tag1'}, 'tag1'), ' ',
                        Builder.node('a', {href:'#', onclick:'return false;', title:'tag2'}, 'tag2'), ' ',
                        Builder.node('a', {href:'#', onclick:'return false;', title:'tag3'}, 'tag3')
                    ])
                ]);
    },

    email: function() {
        divClass = 'text ' + fs.get(this.id, 'size');
        divId   = 'field' + this.id;
        block = Builder.node('input', {type:'text',value:'@',readonly:'readonly', id:divId, className:divClass});
        return Builder.node('div',[block]);
    },

    url: function() {
        divClass = 'text ' + fs.get(this.id, 'size');
        divId   = 'field' + this.id;
        block =  Builder.node('input', {type:'text',value:'http://',readonly:'readonly', id:divId, className:divClass});
        return Builder.node('div',[block]);
    },

    number: function() {
        divClass = 'text ' + fs.get(this.id, 'size');
        divId   = 'field' + this.id;
        block =  Builder.node('input', {type:'text',value:'0123456789', readonly:'readonly', id:divId, className:divClass});
        return Builder.node('div',[block]);
    },

    section: function(){
        return Builder.node('p', {id:'instructions'+fs.get(this.id, 'id')}, fs.get(this.id, 'instructions'));
    },
*/
    additional: function() {
        isUnique = fs.get(this.id, 'isUnique');
        isPrivate = fs.get(this.id, 'isPrivate');
        limit = fs.get(this.id, 'limit')

        //p = Builder.node('p', {className:'hide'});
        //if(isUnique == '1') {p.innerHTML += "Unique";Element.removeClassName(p, 'hide');}
        //if(limit != '') p.innerHTML +=  " "+fs.get(this.id, 'limitMin')+" - "+fs.get(this.id, 'limitMax')+" "+capitalize(fs.get(this.id, 'limit'));
        //return p;
    }

};
var fieldset = Class.create();

fieldset.prototype = {

    // empty JSON object - main database.
    initialize: function() {
        this.data   =   {'fields':[]};
    },

    // Add a new field with default values to the JSON database.
    newField: function(type, id, ctrl) {
        this.data['fields'].push({
            'title'         :   'Untitled',
            'instructions'  :   '',
            'size'          :   'medium',
            'isRequired'    :   '0',
            'isUnique'      :   '0',
            'isPrivate'     :   '0',
            'regex'         :   '',
            'type'          :   type,
            'options'       :   [{"option" : "First choice", 'isDefault':0, 'hasDbColumn':'0', 'id':'0'},
                                    {"option" : "Second choice", 'isDefault':0, 'hasDbColumn':'0', 'id':'0'},
                                    {"option" : "Third choice", 'isDefault':0, 'hasDbColumn':'0', 'id':'0'}],
            'object'            :   ctrl,
            'limit'         : '',
            'limitMin'      : '',
            'limitMax'      : '',
            'position'      : id,
            'id'                : id,
            'hasDbColumn'   : '0',
            'choicesText'   : '',
            'defaultVal'    : '',
            'validation'    : ''
        });
    },

    // Get any value from the JSON database.
    get : function(id, name) {
        el = this.data['fields'].detect(function(num){return num.id == id;});
        return el[name];
    },

    // Set a value inside the JSON database.
    set: function(id, name, value) {
        this.data['fields'].each(function(num, index){
            if(value.replace) value = value.replace(/\\\"/g,"\\ \"");
            if(num.id == id) num[name] = value;
        });
    },

    // Option contains an array of options. Set an individual option with this function.
    setOption: function(id, value, pos) {
        if(value.replace) value = value.replace(/\\\"/g,"\\ \"");
        this.data['fields'].each(function(num, index){
            if(num.id == id) num.options[pos].option = value;
        });
    },

    // Used for the star system that selects default option
    setDefaultOption: function(pos, id) {
        this.data['fields'].each(function(num, index){
            if(num.id == id) {
                num.options.each(function(numSub, index) {
                    if(index == pos && numSub.isDefault == 0) numSub.isDefault = 1;
                    else if(index == pos && numSub.isDefault == 1) numSub.isDefault = 0;
                    else if(num.type != 'checkbox') numSub.isDefault = 0;
                })
            }
        });
    },

    // Remove a field using splice
    removeField: function(id) {
        this.data['fields'].detect(function(num, index){
            if(num.id == id) fs.data['fields'].splice(index, 1);
        });
    },

    //Return a handle on the next field - if there is no next field, optionally search for previous
    nextField: function(position) {
        var nextIndex;
        nextIndex = this.getField(position+1);
        if(!nextIndex) nextIndex = this.getField(position-1);
        if(!nextIndex) return '';
        else return this.data.fields[nextIndex];
    },

    // Return the first field by position
    getField: function(pos, val) {
        var first;
        this.data['fields'].each(function(num, index){
            if(num.position == pos){
                (val)
                    ? first =  num[val]
                    : first = index;
            }
        });
        return first;
    },

    // Prepare the data for Ajax call. Need to remove and reinsert the object property.
    stringify: function() {
        saveFields = new Array();
        this.data['fields'].each(function(num, index){
            saveFields.push(num.object);
            num.object = '';
        });
        ret = JSON.stringify(this.data);
        this.data['fields'].each(function(num, index){
            num.object = saveFields[index];
        });
        return ret;
    }

};
var form = Class.create();

form.prototype = {

    initialize: function() {
        this.data = {
            id: '0',
            name: 'Untitled Form',
            description: 'This is my form. Please fill it out. It\'s awesome.',
            redirect: '',
            redirectmessage: 'Success! Thanks for filling out my form!',
            password: '',
            email: '',
            offsetHeight: '',
            replyTo: '',
            receiptReplyTo: '',
            fromAddress: '',
            receiptMessage: '',
            receiptCopy: '',
            uniqueIP: '0'
        }
    },

    display: function() {
        this.li = Builder.node('li', {id:'myform', className:'info'});
        this.addMarkup();
        return this.li;
    },

    addMarkup: function() {
        this.li.appendChild(Builder.node('a', {href:'#', onclick:'return false;', className:'hvr', title:'Click to edit.'}, [
            this.formLabel(),
            this.formDescription()
        ]));
        this.li.innerHTML = '<div class="arrow"></div>' + this.li.innerHTML;
    },

    // Change the class of a slected field, and display the arrow.
    selected: function() {
        Element.addClassName(this.li,'editing');
    },

    // Remove the class and arrow from the field.
    unselect: function() {
        Element.removeClassName(this.li,'editing');
    },

    /*-----------------------------------
                   FORM MARKUP
    ------------------------------------*/

    formLabel: function() {
        labelId     = 'fname';
        labelVal = this.data['name'];
        return Builder.node('h2',{id:labelId},labelVal);
    },

    formDescription: function() {
        labelId     = 'fdescription';
        labelVal = this.data['description'].replace(/\n/g, "<br />");
        return Builder.node('p', {id:labelId}, labelVal);
    }

};var urlInHistory = 'http://';
var tempEmail = '';
var tempPassword = '';

var formProperties = Class.create();

formProperties.prototype = {

    initialize: function() {},

    display: function() {
        this.name();
        this.description();
        this.email();
        this.receipt();
        this.password();
        this.ip();
        this.redirect();
        Form.focusFirstElement('formProperties');
    },

    name: function() {
        fieldVal = activeForm.data['name'];
        $('formName').value = fieldVal;
        $('formName').value = $('formName').value;
    },

    description: function() {
        fieldVal = activeForm.data['description'];
        $('formDescription').value = fieldVal;
    },

    email: function() {
        fieldVal = activeForm.data['email'];
        $('formEmailVal').value = fieldVal;
        this.setReplyTo();

        $('formEmail').onclick = function() {
            if(Element.hasClassName('formEmailDiv', 'hide')) {
                Element.removeClassName('formEmailDiv','hide');
                updateForm(tempEmail, 'email');
                $('formEmailVal').value = tempEmail;
                Field.activate($('formEmailVal'));
            }
            else {
                Element.addClassName('formEmailDiv','hide');
                tempEmail = $('formEmailVal').value;
                updateForm('', 'email');
            }
        }

        if(fieldVal == '') {$('formEmail').checked = false; Element.addClassName('formEmailDiv','hide');}
        else {$('formEmail').checked = true; Element.removeClassName('formEmailDiv','hide');}
    },

    setReplyTo: function() {
        replyTo = activeForm.data['replyTo'];
        sel = $('formReplyTo');
        sel.options.length = 0;
        sel.options[0] = new Option('', '');
        var x = 1;

        for(var i = 0; i < fs.data['fields'].length; i++) {
            if(fs.data['fields'][i].type == 'email') {
                colId = fs.data['fields'][i].id;
                if(colId >= 0) {
                    sel.options[x] = new Option(fs.data['fields'][i].title,colId);
                    if(colId == replyTo) sel.selectedIndex = x;
                    x++;
                }
            }
        }

        if(x == 1) {
            sel.options[0] = new Option('No Email Fields Found', '');
            sel.disabled = true;
        }
        else sel.disabled = false;
    },

    receipt: function() {
        hasSendTo = this.setSendTo();

        $('formReceipt').onclick = function() {
            if(Element.hasClassName('formReceiptDiv', 'hide')) {
                Element.removeClassName('formReceiptDiv','hide');
            }
            else {
                Element.addClassName('formReceiptDiv','hide');
            }
        }

        if(!hasSendTo) {$('formReceipt').checked = false; Element.addClassName('formReceiptDiv','hide');}
        else {
            $('formReceipt').checked = true;
            $('receiptReplyTo').value = activeForm.data['receiptReplyTo'];
            Element.removeClassName('formReceiptDiv','hide');
        }
    },

    setSendTo: function() {
        sel = $('formSendTo');
        ret = false;
        sel.options.length = 0;
        sel.options[0] = new Option('', '');
        var x = 1;

        for(var i = 0; i < fs.data['fields'].length; i++) {
            if(fs.data['fields'][i].type == 'email') {
                colId = fs.data['fields'][i].id;
                sel.options[x] = new Option(fs.data['fields'][i].title,colId);
                if(fs.data['fields'][i].validation == 'email') {
                    sel.selectedIndex = x;
                    ret = true;
                }
                x++;
            }
        }

        if(x == 1) {
            sel.options[0] = new Option('No Email Fields Found', '');
            sel.disabled = true;
        }
        else sel.disabled = false;

        return ret;
    },

    password: function() {
        fieldVal = activeForm.data['password'];
        $('formPasswordVal').value = fieldVal;

        if(permissions.planId != '1') {
            $('formPassword').onclick = function() {
                if(Element.hasClassName('formPasswordDiv', 'hide')) {
                    Element.removeClassName('formPasswordDiv','hide');
                    updateForm(tempPassword, 'password');
                    $('formPasswordVal').value = tempPassword;
                    Field.activate($('formPasswordVal'));
                }
                else {
                    Element.addClassName('formPasswordDiv','hide');
                    tempPassword = $('formPasswordVal').value;
                    updateForm('', 'password');
                }
            }
            if(fieldVal == '') {$('formPassword').checked = false; Element.addClassName('formPasswordDiv','hide');}
            else {$('formPassword').checked = true; Element.removeClassName('formPasswordDiv','hide');}
        }
        else {
            $('formPassword').disabled = true;
        }
    },

    ip: function() {
        fieldVal = activeForm.data['uniqueIP'];
        if(fieldVal == 1) $('formIp').checked = true;
        else $('formIp').checked = false;
    },

    redirect: function() {
        if(permissions.planId == '1') $('formRedirect').disabled = true;

        message = activeForm.data['redirectmessage'];
        url = activeForm.data['redirect'];

            if(url != '') {
                Element.addClassName($('formMessageVal'), 'hide');
                Element.removeClassName($('formRedirectVal'), 'hide');
                $('formRedirect').checked = true;
                $('formRedirectVal').value = url;
            }
            else {
                Element.addClassName($('formRedirectVal'), 'hide');
                Element.removeClassName($('formMessageVal'), 'hide');
                $('formMessage').checked = true;
                $('formMessageVal').value = message;
            }

    }

}/*-----------------------------------
       GLOBAL VARIABLES
------------------------------------*/

var fs              = new fieldset();       // Our JSON database
var fieldcount  = 0;                        // Autoincrementing unique field ID
var activeField;                                // Currently selected field
var fieldDisplay;                               // The sidebar window that shows field properties
var formDisplay;                                // The sidebar window that shows form properties
var activeForm;                             // Current form
var activePulse = false;

/*-----------------------------------
             ONLOAD
------------------------------------*/
Event.observe(window, 'load', init, false);

function init() {
    initCtrlList();
    initCtrlTypeList();
    showSidebar('addFields');


    fieldDisplay = new fieldProperties(1);
    addForm();
    $('myform').style.display = 'none';
    checkLoad();
    Event.observe($('saveForm'), 'click', saveForm, false);
    initDragDropAdd();
    hideStatus();
    /*
    if(permissions.upload == '0') {
        Event.observe($('fu'), 'click',function(){
            (this.nextSibling && this.nextSibling.id == 'tooltip')
                ? Element.removeTitle(this.nextSibling)
                : Element.showTitle(this);
        }.bind($('fu')), false);
    }*/
}

function initCtrlList() {
    var types = ft.types;
    for(var i=0; i<types.length; i++) {
        var column = (i%2==0) ? 'col1' : 'col2';
        $(column).innerHTML += '<li><a id="sl" href="javascript:addControl(\''
            +types[i].type+'\')" >'
            +types[i].name+'</a></li>';
    }
}

function initCtrlTypeList() {
    var types = ft.types;
    for(var i=0; i<types.length; i++) {
        $('fieldType').appendChild(
            Builder.node('option', {value: types[i].type}, [types[i].name]));
    }
}

function checkLoad() {
    loc = window.location.toString();
    if(loc.substring(loc.length - 12, loc.length) != 'admin/build/') {
        loadFields();
        loadForm();
    }
    else {
        $('myform').style.display = 'block';
        $('nofields').style.display = 'block';
    }
}

/*-----------------------------------
           LOAD FORM
------------------------------------*/

function addForm() {
    ctrl = new form();
    activeForm = ctrl;
    markup = ctrl.display();
    $('formFields').insertBefore(markup, $('formFields').lastChild);
    attachFormEvents(ctrl);
}

function attachFormEvents(ctrl) {
    Event.observe(ctrl.li, 'mousedown', selectForm.bind(ctrl), false);
}

/*-----------------------------------
          ADD NEW FIELD
------------------------------------*/

// Main for adding a new control. Calls necessary functions.
function addControl(type) {
    if(type != 'pagebreak' && hasControlPermission(type)) {
        $('nofields').style.display = 'none';
        if(type == 'currency') type = 'money';
        ctrl = initControl(type);

        if(type == 'address') {
            fs.set(ctrl.id, 'size', 'large');
            fs.set(ctrl.id, 'choicesText', 'Street Address');
        }

        if(type == 'shortname') {
            fs.set(ctrl.id, 'size', '');
            fs.set(ctrl.id, 'choicesText', 'First');
        }

        displayControl(ctrl);
        attachFieldEvents(ctrl);
        showSaveButton();
        initDragDrop();
        updatePositions('true');
    }
}

function hasControlPermission(type, editing) {
    return true;
    if(type == 'file' && permissions.upload == '0') {
        return false;
    }
    if(fs.data['fields'].length == permissions.fieldcount && !editing) {
        lightbox('Upgrade Required', 'In order to add more fields, you must upgrade your Wufoo subscription. To do so, click on the "Account" link at the top of this page.');
        return false;
    }
    else return true;
}

// Initiate a new instance of the field class.
function initControl(type) {
    pos = generateId(type);
    ctrl = new field(pos);
    fs.newField(type, pos, ctrl);
    return ctrl;
}

// Display the new field class to the page, and animate it in.
function displayControl(ctrl) {
    markup = ctrl.display();
    markup.style.display = 'none';
    $('formFields').appendChild(markup);
    Effect.Appear(markup, { duration: 1 });
}

// Change cursor when dragging, and select the element when clicked.
function attachFieldEvents(ctrl) {
    Event.observe(ctrl.li, 'click', selectField.bind(ctrl), false);
    Event.observe(ctrl.li, 'mousedown', function(){this.style.cursor = 'move';}.bind(ctrl.li), false);
    Event.observe(ctrl.li, 'mouseup', function(){this.style.cursor = 'pointer';}.bind(ctrl.li), false);
}

// Grow the height of the page if needed, and also show the Save button.
function showSaveButton() {
    Element.removeClassName('formButtons','hide');
}

// A unique ID for each field
function generateId(type) {
    ret = fieldcount;
    fieldcount += 1;
    if(type == 'address') fieldcount += 5;
    if(type == 'shortname') fieldcount += 3;
    if(type == 'name') fieldcount += 3;
    if(type == 'checkbox') fieldcount += 100;
    return ret;
}

/*-----------------------------------
          SELECT A FIELD
------------------------------------*/

// When the user clicks on a field, that field becomes the active field.
function selectField() {
    unselectAllFields();
    activeForm.unselect();
    this.selected();
    activeField = this.id;
    secondTab();
    showProperties();
    $('fieldProperties').style.marginTop = Position.cumulativeOffset(this.li)[1] - 146 + 'px';
    setTimeout('snapFieldProperties()', 300);
    //new Effect.Highlight('side', {startcolor:'#FFF7C0', endcolor:'#FDFCE9'});
}

function snapFieldProperties() {
    $('fieldProperties').style.marginTop = Position.cumulativeOffset(fs.get(activeField, 'object').li)[1] - 146 + 'px';
}

function selectFieldManually() {
    unselectAllFields();
    activeForm.unselect();
    fs.get(activeField, 'object').selected();
    activeField = activeField;
    secondTab();
    showProperties();
}

// Remove the 'editing' class name from all fields.
function unselectAllFields() {
    fs.data['fields'].each(function(num, index) {
        num.object.unselect();
    })
    $('noFieldSelected').style.display = 'block';
    $('fieldPos').style.display = 'none';
    $('allProps').style.display = 'none';
    $('listButtons').style.display = 'none';
}

/*-----------------------------------
      FIELD PROPERTIES
------------------------------------*/

// Change sidebar to field properties when a field is selected.
function showProperties() {
    showSidebar('fieldProperties');
    fieldDisplay = new fieldProperties(activeField);
    fieldDisplay.display();
}

// If a property is changed, this change needs to be added to the JSON database, and the field display needs to be updated.
function updateProperties(value, place, pos) {
    if(hasControlPermission(value, true)) {
    (place != 'choices')
        ? fs.set(activeField, place, value)
        : fs.setOption(activeField, value, pos);
    liveChanges[place](value);
    }
}

liveChanges = {

    // Update the display of the title. Be sure to put the asterix in if it is required.
    title: function(value) {
        if($('title' + activeField))$('title' + activeField).innerHTML = value;
        this.isRequired(fs.get(activeField, 'isRequired'));
    },

    instructions: function(value){
        if($('instructions' + activeField))$('instructions' + activeField).innerHTML = value;
    },

    // Change the type of the field. Requires visual change as well as a refresh of the properties window.
    type: function(value) {
        if(value != 'date' && value != 'eurodate' &&
           value != 'phone' && value != 'europhone') {
        newId = generateId(value);
        fs.set(activeField, 'id', newId);
        activeField = newId;

        if(value == 'name') {
            fs.set(activeField, 'size', '');
            fs.set(activeField, 'choicesText', 'Title');
        }

        if(value == 'shortname') {
            fs.set(activeField, 'size', '');
            fs.set(activeField, 'choicesText', 'First');
        }

        if(value == 'address') {
            fs.set(activeField, 'size', 'large');
            fs.set(activeField, 'choicesText', 'Street Address');
        }

        }

        this.redraw();
        fieldDisplay.id = activeField;
        fieldDisplay.display();
    },

    // Change the size of the field by changing the CSS class.
    // textarea doesn't push fieldActions down if you don't redraw.
    size: function(value) {
        $('field' + activeField).className = 'text ' + fs.get(activeField,'type') + ' ' +value;
        this.redraw();
    },

    // If a field is required, add a red asterix to the end of the title.
    isRequired: function(value) {
        (value == '1')
            ?   $('title' + activeField).innerHTML += ' <span class="req">*</span>'
            :   $('title' + activeField).innerHTML = fs.get(activeField, 'title');
    },

    // Redraw the field, which in turn will add the appropriate text if the field is unique.
    isUnique: function() {
        this.redraw();
    },

    // Redraw the field, which in turn will add the appropriate text if the field is private.
    isPrivate: function(value) {
        (value == 1)
            ? Element.addClassName(fs.get(activeField, 'object').li, 'private')
            : Element.removeClassName(fs.get(activeField, 'object').li, 'private');
    },

    // If there is a limit, display the min and max range fields.
    limit: function() {
        fieldDisplay.display();
        this.redraw();
    },

    // Redraw the field to reflect changes.
    limitMin: function() {
        this.redraw();
    },

    // Redraw the field to reflect changes.
    limitMax: function() {
        this.redraw();
    },

    // Redraw the field to reflect changes.
    choices: function() {
        this.redraw();
    },

    validation: function() {
        this.redraw();
    },

    defaultVal: function() {

    },

    // Completely erase the field and redraw it.
    redraw: function() {
        fs.get(activeField, 'object').li.innerHTML = '';
        fs.get(activeField, 'object').li.id = 'li_'+activeField;
        fs.get(activeField, 'object').id = activeField;
        fs.get(activeField, 'object').addMarkup();
        fs.get(activeField, 'object').selected();
    }

}

// Add a choice to the properties window for select elements, radio, checkboxes, etc.
function addChoice(pos) {
    fs.get(activeField, 'options').splice(pos, 0, {'option' : '', 'isDefault':'0', 'hasDbColumn':'0', 'id':'0'});
    fieldDisplay.choices();
    updateProperties('', 'choices', pos);
    if($('choice'+(pos)))Field.focus('choice'+pos);
}

// Remove a choice to the properties window for select elements, radio, checkboxes, etc.
function removeChoice(pos) {
    if(pos == 0 && fs.get(activeField, 'options').length == 1) fs.get(activeField, 'options')[0].option = '';
    else fs.get(activeField, 'options').splice(pos, 1);
    fieldDisplay.choices();
    liveChanges['choices']();
    ($('choice'+(pos-1)))
        ? Field.focus('choice'+(pos-1))
        : Field.focus('choice'+(pos));
}

function removeCheckbox(id, db, type, num) {
    if(type == 'checkbox' && fs.get(activeField, 'options').length == 1) {
        alert('A minimum of one choice is required for this field.');
        return false;
    }
    if(type == 'checkbox' && db == 1) confirmed = confirm('Deleting this choice will also delete all data associated with it. This cannot be undone. Are you sure you want to delete this choice?');
    else confirmed = true;

    if(confirmed) {
        if(db == 1 && type == 'checkbox') {
        $('statusText').innerHTML = 'Deleting field ...';
        var myAjax = new Ajax.Request(
            '/admin/build/'+sg_form+'/delete/',
            {
                method: 'post',
                parameters: 'ColumnId='+id+'&type=text&count=1',
                onComplete: function(response) {
                    if(!response.responseText || response.responseText == '') {
                        removeChoice(num);
                    }
                    else lightbox('Error deleting your choice!', response.responseText);
                }
            });
        }
        else {
            removeChoice(num);
        }
    }
}

// Make choice the default choice
function makeDefault(pos) {
    fs.setDefaultOption(pos, activeField);
    fieldDisplay.choices();
    fs.get(activeField, 'object').li.innerHTML = '';
    fs.get(activeField, 'object').addMarkup();
    fs.get(activeField, 'object').selected();
}

/*-----------------------------------
          SELECT A FORM
------------------------------------*/

// When the user clicks on a field, that field becomes the active field.
function selectForm(ctrl) {
    unselectAllFields();
    this.selected();
    thirdTab();
    showFormProperties();
}

/*-----------------------------------
      FORM PROPERTIES
------------------------------------*/

function updateForm(value, place) {
    if(value.replace) value = value.replace(/\\\"/g,"\\ \"");
    activeForm.data[place] = value;
    if(formChanges[place]) formChanges[place](value);
}

formChanges = {

    name: function(value) {
        $('fname').innerHTML = value;
    },

    description: function(value) {
        $('fdescription').innerHTML = value.replace(/\n/g, "<br />");
    }

}

/*-----------------------------------
      TOGGLE SIDEBAR
------------------------------------*/

// Called from Flash - shows the add new field sidebar
function showFields(pulse) {
    unselectAllFields();
    activeForm.unselect();
    showSidebar('addFields');
    firstTab();
    if(pulse == true && !activePulse) {
        activePulse = true;
        new Effect.Highlight('side', {startcolor:'#FFF7C0', endcolor:'#FDFCE9', afterFinish:function(){activePulse = false;}});
    }
}

// Called from Flash - shows the field properties   and defaults to 1st field
function showFieldProperties() {
    if(fs.data['fields'].length == 0) {
        $('nofields').style.display = 'block';
        unselectAllFields();
        Element.addClassName('formButtons','hide');
        activeForm.unselect();
    }
    else {
        if(!activeField) {
            activeField = fs.getField(0, 'id');
            $('noFieldSelected').style.display = 'block';
            $('fieldPos').style.display = 'none';
            $('allProps').style.display = 'none';
        }
        //selectFieldManually();
        //$('fieldProperties').style.marginTop = Position.cumulativeOffset(fs.getField(activeField, 'object').li)[1] - 146 + 'px';
        //$('fieldPosition').style.marginTop = Position.cumulativeOffset(fs.getField(activeField, 'object').li)[1] - 100 + 'px';
    }
    showSidebar('fieldProperties');
    secondTab();
}

// Called from Flash - shows the form properties sidebar
function showFormProperties() {
    unselectAllFields();
    activeForm.selected();
    showSidebar('formProperties');
    formDisplay = new formProperties();
    formDisplay.display();
    thirdTab();
}

// Show the active sidebar.
function showSidebar(name) {
    hideSidebars();
    toggleDisplay(name, 'block');
}

// Hide all sidebars just before showing.
function hideSidebars() {
    toggleDisplay('addFields', 'none');
    toggleDisplay('fieldProperties', 'none');
    toggleDisplay('formProperties', 'none');
}

// Toggle the CSS display of elements.
function toggleDisplay(element, visible) {
    $(element).style.display = visible;
}

/*-----------------------------------
     REMOVE & DUPLICATE
------------------------------------*/

function removeField(id) {
    if(fs.get(id, 'hasDbColumn') == '1') {
        confirmed = confirm('Deleting this field will also delete all data associated with it. This cannot be undone. Are you sure you want to delete this field?');
    }
    else confirmed = true;
    if(confirmed) {
        var id = fs.get(id, 'id');
        removeFromEmailSettings(fs.get(id, 'type'), id);
        removeFromDatabase(id);
    }
}

function removeFromEmailSettings(type, id) {
    if(type == 'email' && activeForm.data.replyTo == id) {
        activeForm.data.replyTo = '';
    }
}

function removeFromDatabase(id) {
    if(fs.get(id, 'hasDbColumn') == '1') {
        var optionCount = 0;
        if(fs.get(id, 'type') == 'checkbox') optionCount = fs.get(id, 'options').length;
        $('statusText').innerHTML = 'Deleting field ...';
        var myAjax = new Ajax.Request(
            '/admin/build/'+sg_form+'/delete/',
            {
                method: 'post',
                parameters: 'ColumnId='+id+'&type='+fs.get(id, 'type'),
                onComplete: function(response) {
                    if(!response.responseText || response.responseText == '') {
                        removeFieldMarkup(id);
                    }
                    else lightbox('Error deleting your field!', response.responseText);
                }
            });
    }
    else removeFieldMarkup(id);
}

function removeFieldMarkup(id) {
    Effect.Fade(fs.get(id, 'object').li, {duration: .5,afterFinish: function(){

        Element.remove(fs.get(id, 'object').li);
        fs.removeField(id);
        updatePositions('true');
        activeField = '';

            if($('fieldProperties').style.display == 'block') showFieldProperties();
            if(fs.data['fields'].length == 0) {showFields(true);}
        }});
}

function duplicateField(id) {
    ctrl = initControl(fs.get(id, 'type'));
    copyData(ctrl, id);
    displayDuplicate(ctrl, id);
    attachFieldEvents(ctrl);
    showSaveButton();
    initDragDrop();
    updatePositions('true');
}

function copyData(ctrl, id) {
    fs.data['fields'].detect(function(num, index){
        if(num.id == id) {
            $H(fs.data['fields'][index]).each(function(fields) {
                if(fields.key != 'id' && fields.key != 'object' && fields.key != 'hasDbColumn') {
                    if(fields.key == 'options') {
                        opts = [];
                        for(var i = 0; i < fields.value.length; i++) {
                            opts.push(clone(fields.value[i]));
                        }
                    }
                    else opts = fields.value;
                    fs.set(ctrl.id, fields.key, opts);
                }
            })
        }
    });

    newval = fs.get(ctrl.id, 'options');
    for(var i = 0; i < newval.length; i++) {
        newval[i].hasDbColumn = '0';
        newval[i].id = '0';
    }
}

function clone(myObj)
{
    if(typeof(myObj) != 'object') return myObj;
    if(myObj == null) return myObj;

    var myNewObj = new Object();

    for(var i in myObj)
        myNewObj[i] = clone(myObj[i]);

    return myNewObj;
}

function displayDuplicate(ctrl, id) {
    markup = ctrl.display();
    markup.style.display = 'none';
    $('formFields').insertBefore(markup, $('li_'+id).nextSibling);
    Effect.Appear(markup, { duration: .5 });
}

/*-----------------------------------
          DRAG AND DROP
------------------------------------*/

// Everytime a new field is added, we need to create a Sortable on the <ul> to make it drag-dropable.
function initDragDrop() {
    Sortable.create('formFields', {onUpdate : function(){setTimeout('updatePositions()', 0);}, only:'dragable'});
}

function initDragDropAdd() {
    //Sortable.create('col1', {containment:['col1'],  constraint:false, dropOnEmpty:true});
    //Sortable.create('col2', {containment:['formFields'],  constraint:false, dropOnEmpty:true});
}

// After the drag and drop is finished, update the position of every field.
function updatePositions(noredraw) {
    fs.data['fields'].each(function(num, index) {
        num.position =  countPreviousSiblings(num.object.li);
    })
    if(noredraw != 'true')fieldDisplay.display();
}

// Determine the position of the field by counting the previous siblings in the list.
function countPreviousSiblings(element) {
    var count = 0;
    while(element.previousSibling && element.previousSibling.className && Element.hasClassName(element.previousSibling, 'dragable')) {
        element = element.previousSibling;
        count++;
    }
    return count;
}

/*-----------------------------------
      KEYBOARD NAV
------------------------------------*/

function choicesKeys(e,pos) {
    if(e.keyCode == Event.KEY_RETURN && browser != 'Safari') {
        addChoice(pos + 1);
    }
    if(e.keyCode == Event.KEY_DELETE && browser != 'Safari') {
        removeChoice(pos);
    }
}

/*-----------------------------------
      CHANGING TABS
------------------------------------*/

// Set focus to first tab
function firstTab() {
     $('tabs').className = "afi";
}

// Set focus to second  tab
function secondTab() {
     $('tabs').className = "cfi";
}

// Set focus to third  tab
function thirdTab() {
     $('tabs').className = "cfo";
}

/*-----------------------------------
           RECEIPTS & EMAILS
------------------------------------*/

function updateReceipt(fieldId) {
    for(var i = 0; i < fs.data['fields'].length; i++) {
        if(fs.data['fields'][i].validation == 'email' && fs.data['fields'][i].type == 'email') {
            fs.data['fields'][i].validation = '';
        }
    }
    fs.set(fieldId, 'validation', 'email');
}

function initReceiptLightbox() {
    Lightbox.showUrl('/lightboxes/receipt.php', populateReceiptLightbox);
}

function populateReceiptLightbox() {
    $('fromAddress').value = activeForm.data['fromAddress'];
    $('receiptMessage').value = activeForm.data['receiptMessage'];
    var copy = activeForm.data['receiptCopy'];
    if(copy == '0') $('receiptCopy').checked = false;
    else {
        $('receiptCopy').checked = true;
        activeForm.data['receiptCopy'] = 1;
    }
}

function updateReceiptCopy(ctrl) {
    if(ctrl.checked) updateForm(1, 'receiptCopy');
    else updateForm(0, 'receiptCopy');
}

/*-----------------------------------
           SAVE FORM
------------------------------------*/

function saveForm() {
    $('statusText').innerHTML = 'Saving form data ...';
    $('saveForm').innerHTML = '<img src="css/images/icons/arrow_refresh.png" /> Saving' ;
    activeForm.data['offsetHeight'] = $('main').offsetHeight;
    Event.stopObserving($('saveForm'), 'click', saveForm, false);
    var myAjax = new Ajax.Request(
        '/admin/build/save.php',
        {
            method: 'post',
            parameters: 'form='+encodeURIComponent(JSON.stringify(activeForm.data))+'&fields='+encodeURIComponent(fs.stringify()),
            onComplete: formDoneSaving
        });
}

function formDoneSaving(originalRequest) {
    if(originalRequest.responseText.length <= 6) {
        if(originalRequest.responseText.replace(/^\s*|\s*$/g,"") == '1') {
            document.location = '/admin/';
        }
        else Lightbox.showUrl('/lightboxes/wdywtdn.php', false ,'modal');
    }
    else {
        $('saveForm').innerHTML = '<img src="css/images/icons/tick.png" /> Save Form' ;
        Event.observe($('saveForm'), 'click', saveForm, false);
        lightbox('Error saving your form!', originalRequest.responseText);
    }
}

/*-----------------------------------
           LOAD FORM
------------------------------------*/

function loadForm() {
    $('myform').style.display = 'block';

    var loaded = formjson;
    updateForm(loaded.id, 'id');
    updateForm(loaded.name, 'name');
    updateForm(loaded.description.replace(/\<br \/\>/g,"\n"), 'description');
    updateForm(loaded.redirect, 'redirect');
    updateForm(loaded.redirectmessage.replace(/\<br \/\>/g,"\n"), 'redirectmessage');
    updateForm(loaded.email, 'email');
    updateForm(loaded.password, 'password');
    updateForm(loaded.replyTo, 'replyTo');
    updateForm(loaded.receiptReplyTo, 'receiptReplyTo');
    updateForm(loaded.fromAddress, 'fromAddress');
    updateForm(loaded.receiptMessage.replace(/\<br \/\>/g,"\n"), 'receiptMessage');
    updateForm(loaded.receiptCopy, 'receiptCopy');
    updateForm(loaded.uniqueIP, 'uniqueIP');
}

function loadFields() {

    var x = 50;

    var loaded = fieldjson;

    loaded.fields.each(function(num, index) {
        // create field
        ctrl = new field(num.id);
        fs.newField(num.type, num.id, ctrl);
        newMax = parseInt(num.id);
        if(num.type == 'address') newMax += 5;
        if(num.type == 'name') newMax += 3;
        if(num.type == 'shortname') newMax += 1;
        if(num.type == 'checkbox') newMax += 100;
        updateFieldCount(newMax);

        //copy over new properties
        $H(loaded.fields[index]).each(function(fields) {
            if(fields.value.replace) newval = fields.value.replace(/\<br \/\>/g,"\n");
            else newval = fields.value;
            fs.set(ctrl.id, fields.key, newval);
        })


        //markup for field
        markup = ctrl.display();
        $('formFields').appendChild(markup);

        // attach events and functionality
        attachFieldEvents(ctrl);
        updatePositions('true');

        x+=50;
    });
    initDragDrop();
}

// fieldCount starts at the greatest loaded ID + 1
function updateFieldCount(num) {
    if(num >= fieldcount) fieldcount = parseInt(num) + 1;
    showSaveButton();
}

